﻿using System;
using System.Collections.Generic;
using System.Text;
using T4UtilityBelt.UxDesigns;
using T4UtilityBelt.UxDesigns.Bindings;
using T4UtilityBelt.UxDesigns.Controls.Renderers;


namespace T4UtilityBelt.Writers
{
    public class CodeWriter
    {
        public CodeWriter(Platforms platform)
        {
            Platform = platform;
            IsFirstElement = true;
        }

        public Platforms Platform { get; private set; }
        public bool IsFirstElement { get; set; }

        private readonly StringBuilder _sb = new StringBuilder();


        public void WriteBeginTag(string tag)
        {
            _sb.Append("<");
            _sb.Append(tag);
            _sb.Append(" ");
        }

        public void WriteFullEndTag(string tag)
        {
            _sb.Append("<");
            _sb.Append(tag);
            _sb.AppendLine("/> ");
        }

        public void WriteFullTag(string tag)
        {
            _sb.Append("<");
            _sb.Append(tag);
            _sb.AppendLine(">");
        }

        public void WriteEnd()
        {
            _sb.AppendLine(">");
        }

        public void WriteFullEnd()
        {
            _sb.AppendLine("/>");
        }

        public void WriteEndTag(string tag)
        {
            _sb.Append("</");
            _sb.Append(tag);
            _sb.AppendLine("> ");
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])")]
        public void WriteAttributeFormat(string property, string format, params  object[] args)
        {
            if (!string.IsNullOrWhiteSpace(format))
            {
                _sb.Append(property);
                _sb.Append(@"=""");
                _sb.Append(string.Format(format, args));
                _sb.Append(@""" ");
            }
        }

        public void AddBinding(string property, Binding value)
        {
            if (value != null)
            {
                RendererHelper.CreateRenderer<IBindingRenderer>(Platform).Render(this, property, value);
            }
        }

        public void AddBinding(string property, Bindable value)
        {
            if (value != null)
            {
                RendererHelper.CreateRenderer<IBindableRenderer>(Platform).Render(this, property, value);
            }
        }

        public void RenderBindingsAttribute()
        {
            RendererHelper.CreateRenderer<IBindingRenderer>(Platform).RenderBindingsAttribute(this, bindingList);
        }

        public void WriteAttribute(string property, string value)
        {
            if (!string.IsNullOrWhiteSpace(value))
            {
                _sb.Append(property);
                _sb.Append(@"=""");
                _sb.Append(value);
                _sb.Append(@""" ");
            }
        }

        public void WriteAttribute<T>(string tag, T? value, T defaultValue)
            where T : struct
        {
            if (!object.Equals(value, defaultValue)
                && value.HasValue)
            {
                WriteAttribute(tag, value.ToString());
            }
        }

        public void WriteAttribute<T>(string tag, T? value)
            where T : struct
        {
            if (value.HasValue)
            {
                WriteAttribute(tag, value.ToString());
            }
        }

        public void WriteAttribute<T>(string tag, T value)
        {
            WriteAttribute(tag, value.ToString());
        }

        public void WriteAttribute<T>(string tag, T value, T defaultValue)
        {
            if (!object.Equals(value, defaultValue))
            {
                WriteAttribute(tag, value.ToString());
            }
        }

        public void Write(string text)
        {
            _sb.Append(text);
        }

        public void WriteLine(string text)
        {
            _sb.AppendLine(text);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])")]
        public void WriteFormat(string format, params object[] args)
        {
            _sb.Append(string.Format(format, args));
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])")]
        public void WriteFormatLine(string format, params object[] args)
        {
            _sb.AppendLine(string.Format(format, args));
        }

        public override string ToString()
        {
            return _sb.ToString();
        }

        BindingDictionary bindingList = new BindingDictionary();
        internal void AddBindingToList(string property, Binding binding)
        {
            if (bindingList.ContainsKey(property))
            {
                throw  new BindingException("Property is already added to the list: " + property);
            }
            bindingList.Add(property, binding);
        }
    }
}